home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / ICProgKit1.0 / Source / API Source / ICRAPI.p < prev   
Text File  |  1994-11-27  |  16KB  |  581 lines

  1. unit ICRAPI;
  2.  
  3. interface
  4.  
  5.     uses
  6. {$ifc undefined THINK_Pascal}
  7.         Types, Files, 
  8. {$endc}
  9.         Components, ICTypes;
  10.  
  11.     type
  12.         ICRRecord = record                    (* this is *completely* private to the implementation!!! *)
  13.                 instance: ComponentInstance;        (* nil if no component available, if not nil then rest of record is junk *)
  14.                 have_config_file: boolean;
  15.                 config_file: FSSpec;
  16.                 config_refnum: integer;
  17.                 perm: ICPerm;
  18.                 inside_begin: boolean;
  19.                 default_filename: Str63;
  20.             end;
  21.         ICRRecordPtr = ^ICRRecord;
  22.  
  23.     function ICRStart (var inst: ICRRecord; creator: OSType): ICError;
  24.     function ICRStop (var inst: ICRRecord): ICError;
  25.  
  26.     function ICRFindConfigFile (var inst: ICRRecord; count: integer; folders: ICDirSpecArrayPtr): ICError;
  27.     function ICRSpecifyConfigFile (var inst: ICRRecord; config: FSSpec): ICError;
  28.  
  29.     function ICRGetSeed (var inst: ICRRecord; var seed: longint): ICError;
  30.     function ICRGetPerm (var inst: ICRRecord; var perm: ICPerm): ICError;
  31.  
  32.     function ICRBegin (var inst: ICRRecord; perm: ICPerm): ICError;
  33.     function ICRGetPref (var inst: ICRRecord; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  34.     function ICRSetPref (var inst: ICRRecord; key: Str255; attr: ICAttr; buf: Ptr; size: longint): ICError;
  35.     function ICRCountPref (var inst: ICRRecord; var count: longint): ICError;
  36.     function ICRGetIndPref (var inst: ICRRecord; n: longint; var key: Str255): ICError;
  37.     function ICRDeletePref (var inst: ICRRecord; key: Str255): ICError;
  38.     function ICREnd (var inst: ICRRecord): ICError;
  39.     function ICRDefaultFileName (var inst: ICRRecord; var name: Str63): ICError;
  40.  
  41. implementation
  42.  
  43.     uses
  44. {$ifc undefined THINK_Pascal}
  45.         Resources, GestaltEqu, OSUtils, Memory, Errors, 
  46. {$endc}
  47.         Aliases, AppleTalk, Folders;
  48.  
  49.     function ICFindFolder(vRefNum: integer; folderType: OSType; createFolder: boolean;
  50.                                                  var foundVRefNum: integer; var foundDirID: longint): OSErr;
  51.          inline $7000,$A823;
  52.  
  53.     const
  54.         Res_Code = 'ICRP';
  55.  
  56.     function ICRStart (var inst: ICRRecord; creator: OSType): ICError;
  57.         var
  58.             junk: ICError;
  59.     begin
  60.         inst.have_config_file := false;
  61.         inst.config_file.vRefNum := 0;
  62.         inst.config_file.parID := 0;
  63.         inst.config_file.name := '';
  64.         inst.config_refnum := 0;
  65.         inst.perm := icNoPerm;
  66.         junk := ICRDefaultFileName(inst, inst.default_filename);
  67.         ICRStart := noErr;
  68.     end; (* ICRStart *)
  69.  
  70.     procedure ICRCloseIfOpen (var inst: ICRRecord);
  71.     begin
  72.         if inst.config_refnum <> 0 then begin
  73.             CloseResFile(inst.config_refnum);
  74.             inst.config_refnum := 0;
  75.         end; (* if *)
  76.         inst.perm := icNoPerm;
  77.     end; (* ICRCloseIfOpen *)
  78.  
  79.     function ICRStop (var inst: ICRRecord): ICError;
  80.     begin
  81.         ICRCloseIfOpen(inst);
  82.         ICRStop := noErr;
  83.     end; (* ICRStop *)
  84.  
  85.     function ICRFindConfigFile (var inst: ICRRecord; count: integer; folders: ICDirSpecArrayPtr): ICError;
  86.  
  87.         function FindPrefFolder (var pref_fold: ICDirSpec): OSErr;
  88.             var
  89.                 err: OSErr;
  90.                 env: SysEnvRec;
  91.                 junk: longint;
  92.                 response: longint;
  93.         begin
  94.             if (Gestalt(gestaltFindFolderAttr, response) = noErr) & btst(response, gestaltFindFolderPresent) then begin
  95.                 (* Gestalt says it's implemented -- call it directly *)
  96.                 err := ICFindFolder(kOnSystemDisk, kPreferencesFolderType, true, pref_fold.vRefNum, pref_fold.dirID);
  97.             end
  98.             else begin
  99.                 (* Simulate the important stuff *)
  100.                 err := SysEnvirons(curSysEnvVers, env);
  101.                 if err = noErr then begin
  102.                     err := GetWDInfo(env.sysVRefNum, pref_fold.vRefNum, pref_fold.dirID, junk);
  103.                 end; (* if *)
  104.             end; (* if *)
  105.             FindPrefFolder := err;
  106.         end; (* FindPrefFolder *)
  107.  
  108.         function ScanFolder (folder: ICDirSpec; var found_file: FSSpec): boolean;
  109.  
  110.             function FoundFile (folder: ICDirSpec; ndx: integer; var found_file: FSSpec): OSErr;
  111.                 var
  112.                     err: OSErr;
  113.                     cpb: CInfoPBRec;
  114.                     is_folder: boolean;
  115.                     was_alias: boolean;
  116.                     response: longint;
  117.             begin
  118.                 with cpb do begin (* safe *)
  119.                     ioVRefNum := folder.vRefNum;
  120.                     ioDirID := folder.dirID;
  121.                     ioNamePtr := @found_file.name;
  122.                     ioFDirIndex := ndx;
  123.                     err := PBGetCatInfoSync(@cpb);
  124.                     if err = noErr then begin
  125.                         found_file.vRefNum := cpb.ioVRefNum;
  126.                         found_file.parID := cpb.ioFlParID;
  127.                         if (btst(cpb.ioFlAttrib, 4) or (cpb.ioFlFndrInfo.fdType <> ICfiletype)) then begin
  128.                             err := 1;
  129.                         end
  130.                         else if (Gestalt(gestaltAliasMgrAttr, response) = noErr) & btst(response, gestaltAliasMgrPresent) then begin
  131.                             err := ResolveAliasFile(found_file, true, is_folder, was_alias);
  132.                             if err <> noErr then begin
  133.                                 err := 1;
  134.                             end; (* if *)
  135.                         end; (* if *)
  136.                     end; (* if *)
  137.                 end; (* with *)
  138.                 FoundFile := err;
  139.             end; (* FoundFile *)
  140.  
  141.             var
  142.                 err: ICError;
  143.                 found: boolean;
  144.                 i: integer;
  145.         begin
  146.             found_file.name := inst.default_filename;
  147.             found := (FoundFile(folder, 0, found_file) = noErr);
  148.             if not found then begin
  149.                 i := 1;
  150.                 repeat
  151.                     found_file.name := '';
  152.                     err := FoundFile(folder, i, found_file);
  153.                     i := i + 1;
  154.                 until err <> 1;
  155.                 found := (err = noErr);
  156.             end; (* if *)
  157.             ScanFolder := found;
  158.         end; (* ScanFolder *)
  159.  
  160.         var
  161.             err: ICError;
  162.             i: integer;
  163.             found: boolean;
  164.             pref_fold: ICDirSpec;
  165.     begin
  166.         ICRCloseIfOpen(inst);                { ! }
  167.         err := noErr;
  168.         i := 0;
  169.         found := false;
  170.         while (i < count) and not found do begin
  171.             found := ScanFolder(folders^[i], inst.config_file);
  172.             i := i + 1;
  173.         end; (* while *)
  174.         if not found then begin
  175.             err := FindPrefFolder(pref_fold);
  176.             if (err = noErr) & not ScanFolder(pref_fold, inst.config_file) then begin
  177.                 inst.config_file.vRefNum := pref_fold.vRefNum;
  178.                 inst.config_file.parID := pref_fold.dirID;
  179.                 inst.config_file.name := inst.default_filename;
  180.             end; (* if *)
  181.         end; (* if *)
  182.         inst.have_config_file := err = noErr;
  183.         ICRFindConfigFile := err;
  184.     end; (* ICRFindConfigFile *)
  185.  
  186.     function ICRSpecifyConfigFile (var inst: ICRRecord; config: FSSpec): ICError;
  187.     begin
  188.         ICRCloseIfOpen(inst);                { ! }
  189.         inst.have_config_file := true;
  190.         inst.config_file := config;
  191.         ICRSpecifyConfigFile := noErr;
  192.     end; (* ICRSpecifyConfigFile *)
  193.  
  194.     function ICRGetSeed (var inst: ICRRecord; var seed: longint): ICError;
  195.         var
  196.             err: ICError;
  197.             cpb: CInfoPBRec;
  198.     begin
  199.         seed := 0;
  200.         err := fnfErr;
  201.         if inst.have_config_file then begin
  202.             with cpb do begin (* safe *)
  203.                 ioVRefNum := inst.config_file.vRefNum;
  204.                 ioDirID := inst.config_file.parID;
  205.                 ioNamePtr := @inst.config_file.name;
  206.                 ioFDirIndex := 0;
  207.             end; (* with *)
  208.             err := PBGetCatInfoSync(@cpb);
  209.             if err = noErr then begin
  210.                 seed := cpb.ioFlMdDat;
  211.             end
  212.             else if err = fnfErr then begin
  213.                 err := noErr;
  214.             end; (* if *)
  215.         end; (* if *)
  216.         ICRGetSeed := err;
  217.     end; (* ICRGetSeed *)
  218.  
  219.     function ICRGetPerm (var inst: ICRRecord; var perm: ICPerm): ICError;
  220.     begin
  221.         perm := inst.perm;
  222.         ICRGetPerm := noErr;
  223.     end; (* ICRGetPerm *)
  224.     
  225.     function ICRPermToFSPerm (perm: ICPerm): integer;
  226.     begin
  227.         case perm of
  228.             icReadOnlyPerm: 
  229.                 ICRPermToFSPerm := fsRdPerm;
  230.             icReadWritePerm: 
  231.                 ICRPermToFSPerm := fsRdWrPerm;
  232.         otherwise
  233.             ICRPermToFSPerm := 0;
  234.         end; (* case *)
  235.     end; (* ICRPermToFSPerm *)
  236.  
  237.     function ICRBegin (var inst: ICRRecord; perm: ICPerm): ICError;
  238.         var
  239.             err: ICError;
  240.             ref: integer;
  241.             junk: OSErr;
  242.     begin
  243.         err := noErr;
  244.         if (inst.perm <> icNoPerm) or (perm = icNoPerm) then begin
  245.             err := paramErr;
  246.         end; (* if *)
  247.         if err = noErr then begin
  248.             ICRCloseIfOpen(inst);                { ! }
  249.             if not inst.have_config_file then begin
  250.                 err := bdNamErr;
  251.             end; (* if *)
  252.         end; (* if *)
  253.         if err = noErr then begin
  254.             ref := HOpenResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICRPermToFSPerm(perm));
  255.             err := ResError;
  256.             if (err = fnfErr) or (err = eofErr) then begin
  257.                 case perm of
  258.                     icReadOnlyPerm:  begin
  259.                         ref := 0;
  260.                         err := noErr;
  261.                     end; (* icReadOnlyPerm *)
  262.                     icReadWritePerm:  begin
  263.                         junk := HCreate(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICcreator, ICfiletype);
  264.                         HCreateResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name);
  265.                         ref := HOpenResFile(inst.config_file.vRefNum, inst.config_file.parID, inst.config_file.name, ICRPermToFSPerm(perm));
  266.                         err := ResError;
  267.                     end; (* icReadWritePerm *)
  268.                 end; (* case *)
  269.             end; (* if *)
  270.         end; (* if *)
  271.         if err = noErr then begin
  272.             inst.config_refnum := ref;
  273.             inst.perm := perm;
  274.         end; (* if *)
  275.         case err of
  276.             opWrErr, permErr: 
  277.                 err := icNoMoreWritersErr;
  278.             otherwise { do nothing }
  279.         end; (* case *)
  280.         ICRBegin := err;
  281.     end; (* ICRBegin *)
  282.  
  283.     function ICRCheckInside (var inst: ICRRecord): ICError;
  284.     begin
  285.         if inst.perm = icNoPerm then begin
  286.             ICRCheckInside := paramErr;
  287.         end
  288.         else begin
  289.             ICRCheckInside := noErr;
  290.         end; (* if *)
  291.     end; (* ICRCheckInside *)
  292.     
  293.     function ICRForceInside(var inst : ICRRecord; perm : ICPerm; var force_info : boolean) : ICError;
  294.         var
  295.             err : ICError;
  296.     begin
  297.         force_info := false;
  298.         if (inst.perm = perm) or ((inst.perm = icReadWritePerm) and (perm = icReadOnlyPerm)) then begin
  299.             err := noErr;
  300.         end else if inst.perm = icNoPerm then begin
  301.             err := ICRBegin(inst, perm);
  302.             force_info := (err = noErr);
  303.         end else begin
  304.             err := icPermErr;
  305.         end; (* if *)
  306.         ICRForceInside := err;
  307.     end; (* ICRForceInside *)
  308.     
  309.     function ICRReleaseInside(var inst : ICRRecord; force_info : boolean) : ICError;
  310.     begin
  311.         if force_info then begin
  312.             ICRReleaseInside := ICREnd(inst);
  313.         end else begin
  314.             ICRReleaseInside := noErr;
  315.         end; (* if *)
  316.     end; (* ICRReleaseInside *)
  317.  
  318.     function ICRGetPref (var inst: ICRRecord; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  319.         var
  320.             err: ICError;
  321.             err2 : ICError;
  322.             max_size: longint;
  323.             true_size: longint;
  324.             old_refnum: integer;
  325.             prefh: Handle;
  326.             force_info : boolean;
  327.     begin
  328.         max_size := size;
  329.         size := 0;
  330.         attr := ICattr_no_change;
  331.         prefh := nil;
  332.         err := ICRForceInside(inst, icReadOnlyPerm, force_info);
  333.         if (err = noErr) and (inst.config_refnum = 0) then begin
  334.             err := icPrefNotFoundErr;
  335.         end; (* if *)
  336.         if (err = noErr) and ((key = '') or ((max_size < 0) and (buf <> nil))) then begin
  337.             err := paramErr;
  338.         end; (* if *)
  339.         if err = noErr then begin
  340.             old_refnum := CurResFile;
  341.             UseResFile(inst.config_refnum);
  342.             err := ResError;
  343.             if err = noErr then begin
  344.                 prefh := Get1NamedResource(Res_Code, key);
  345.                 err := ResError;
  346.                 if prefh = nil then begin
  347.                     err := icPrefNotFoundErr;
  348.                 end; (* if *)
  349.                 if err = noErr then begin
  350.                     true_size := GetHandleSize(prefh);
  351.                     if true_size < 4 then begin
  352.                         err := icPrefDataErr;
  353.                     end; (* if *)
  354.                 end; (* if *)
  355.                 if err = noErr then begin
  356.                     size := true_size - 4;
  357.                     attr := longintPtr(prefh^)^;
  358.                     if (buf <> nil) and (size <> 0) then begin
  359.                         if size > max_size then begin
  360.                             err := icTruncatedErr;
  361.                         end
  362.                         else begin
  363.                             max_size := size;
  364.                         end; (* if *)
  365.                         BlockMove(ptr(longint(prefh^) + 4), buf, max_size);
  366.                     end; (* if *)
  367.                 end; (* if *)
  368.                 UseResFile(old_refnum);
  369.             end; (* if *)
  370.         end; (* if *)
  371.         if prefh <> nil then begin
  372.             ReleaseResource(prefh);
  373.         end; (* if *)
  374.         err2 := ICRReleaseInside(inst, force_info);
  375.         if err = noErr then begin
  376.             err := err2;
  377.         end; (* if *)
  378.         ICRGetPref := err;
  379.     end; (* ICRGetPref *)
  380.  
  381.     function ICRSetPref (var inst: ICRRecord; key: Str255; attr: ICAttr; buf: Ptr; size: longint): ICError;
  382.         var
  383.             err: ICError;
  384.             err2 : ICError;
  385.             old_attr: longint;
  386.             old_refnum: integer;
  387.             prefh: Handle;
  388.             id: integer;
  389.             force_info : boolean;
  390.     begin
  391.         prefh := nil;
  392.         if buf = nil then begin
  393.             size := 0;
  394.         end;
  395.         err := ICRForceInside(inst, icReadWritePerm, force_info);
  396.         if (err = noErr) and (inst.perm <> icReadWritePerm) then begin
  397.             err := icPermErr;
  398.         end; (* if *)
  399.         if (err = noErr) and (inst.config_refnum = 0) then begin
  400.             err := icInternalErr;
  401.         end; (* if *)
  402.         if (err = noErr) and ((key = '') or (size < 0)) then begin
  403.             err := paramErr;
  404.         end; (* if *)
  405.         if err = noErr then begin
  406.             old_refnum := CurResFile;
  407.             UseResFile(inst.config_refnum);
  408.             err := ResError;
  409.             if err = noErr then begin
  410.                 prefh := Get1NamedResource(Res_Code, key);
  411.                 if (prefh <> nil) & (GetHandleSize(prefh) < 4) then begin { very bad! }
  412.                     RmveResource(prefh);
  413.                     DisposeHandle(prefh);
  414.                     prefh := nil;
  415.                 end;
  416.                 if (prefh = nil) then begin
  417.                     old_attr := 0;
  418.                 end
  419.                 else begin
  420.                     old_attr := longintPtr(prefh^)^;
  421.                 end;
  422.                 if attr = ICattr_no_change then begin
  423.                     attr := old_attr;
  424.                 end; (* if *)
  425.                 if btst(old_attr, ICattr_locked_bit) and btst(attr, ICattr_locked_bit) and (buf <> nil) then begin
  426.                     err := icPermErr;
  427.                 end; (* if *)
  428.                 if (prefh = nil) then begin
  429.                     prefh := NewHandle(size + 4);
  430.                     err := MemError;
  431.                     if err = noErr then begin
  432.                         repeat
  433.                             id := Unique1ID(Res_Code);
  434.                         until id > 127;
  435.                         AddResource(prefh, Res_Code, id, key);
  436.                         err := ResError;
  437.                         if err <> noErr then begin
  438.                             DisposeHandle(prefh);
  439.                             prefh := nil;
  440.                         end; (* if *)
  441.                     end; (* if *)
  442.                 end; (* if *)
  443.                 if (err = noErr) & (buf <> nil) then begin
  444.                     SetHandleSize(prefh, size + 4);
  445.                     err := MemError;
  446.                 end; (* if *)
  447.                 if (err = noErr) & (size > 0) then begin
  448.                     BlockMove(buf, ptr(longint(prefh^) + 4), size);
  449.                 end; (* if *)
  450.                 if (err = noErr) then begin
  451.                     longintPtr(prefh^)^ := attr;
  452.                     ChangedResource(prefh);
  453.                     WriteResource(prefh);
  454.                     err := ResError;
  455.                 end; (* if *)
  456.                 UseResFile(old_refnum);
  457.             end; (* if *)
  458.         end; (* if *)
  459.         if prefh <> nil then begin
  460.             ReleaseResource(prefh);
  461.         end; (* if *)
  462.         err2 := ICRReleaseInside(inst, force_info);
  463.         if err = noErr then begin
  464.             err := err2;
  465.         end; (* if *)
  466.         ICRSetPref := err;
  467.     end; (* ICRSetPref *)
  468.  
  469.     function ICRCountPref (var inst: ICRRecord; var count: longint): ICError;
  470.         var
  471.             err: ICError;
  472.             old_refnum: integer;
  473.     begin
  474.         err := ICRCheckInside(inst);
  475.         if (err = noErr) and (inst.config_refnum = 0) then begin
  476.             count := 0;
  477.         end
  478.         else begin
  479.             old_refnum := CurResFile;
  480.             UseResFile(inst.config_refnum);
  481.             err := ResError;
  482.             if err = noErr then begin
  483.                 count := Count1Resources(Res_Code);
  484.                 err := ResError;
  485.                 UseResFile(old_refnum);
  486.             end; (* if *)
  487.         end; (* if *)
  488.         if err <> noErr then begin
  489.             count := 0;
  490.         end; (* if *)
  491.         ICRCountPref := err;
  492.     end; (* ICRCountPref *)
  493.  
  494.     function ICRGetIndPref (var inst: ICRRecord; n: longint; var key: Str255): ICError;
  495.         var
  496.             err: ICError;
  497.             old_refnum: integer;
  498.             prefh: Handle;
  499.             junk_id: integer;
  500.             junk_type: ResType;
  501.     begin
  502.         prefh := nil;
  503.         err := ICRCheckInside(inst);
  504.         if (err = noErr) and (n < 1) then begin
  505.             err := paramErr;
  506.         end; (* if *)
  507.         if (err = noErr) and (inst.config_refnum = 0) then begin
  508.             err := icPrefNotFoundErr;
  509.         end
  510.         else begin
  511.             old_refnum := CurResFile;
  512.             UseResFile(inst.config_refnum);
  513.             err := ResError;
  514.             if err = noErr then begin
  515.                 SetResLoad(false);
  516.                 prefh := Get1IndResource(Res_Code, n);
  517.                 SetResLoad(true);
  518.                 if prefh = nil then begin
  519.                     err := icPrefNotFoundErr;
  520.                 end
  521.                 else begin
  522.                     GetResInfo(prefh, junk_id, junk_type, key);
  523.                     err := ResError;
  524.                 end; (* if *)
  525.                 UseResFile(old_refnum);
  526.             end; (* if *)
  527.         end; (* if *)
  528.         if prefh <> nil then begin
  529.             ReleaseResource(prefh);
  530.         end; (* if *)
  531.         ICRGetIndPref := err;
  532.     end; (* ICRGetIndPref *)
  533.  
  534.     function ICRDeletePref (var inst: ICRRecord; key: Str255): ICError;
  535.         var
  536.             err : ICError;
  537.             prefh : Handle;
  538.             old_refnum : integer;
  539.     begin
  540.         err := ICRCheckInside(inst);
  541.         if (err = noErr) and (key = '') then begin
  542.             err := paramErr;
  543.         end; (* if *)
  544.         if err = noErr then begin
  545.             old_refnum := CurResFile;
  546.             UseResFile(inst.config_refnum);
  547.             err := ResError;
  548.             if err = noErr then begin
  549.                 SetResLoad(false);
  550.                 prefh := Get1NamedResource(Res_Code, key);
  551.                 err := ResError;
  552.                 SetResLoad(true);
  553.                 if prefh = nil then begin
  554.                     err := icPrefNotFoundErr;
  555.                 end; (* if *)
  556.                 if err = noErr then begin
  557.                     RmveResource(prefh);
  558.                     err := ResError;
  559.                 end; (* if *)
  560.                 UseResFile(old_refnum);
  561.             end; (* if *)
  562.         end; (* if *)
  563.         ICRDeletePref := err;
  564.     end; (* ICRDeletePref *)
  565.     
  566.     function ICREnd (var inst: ICRRecord): ICError;
  567.         var
  568.             err: ICError;
  569.     begin
  570.         err := ICRCheckInside(inst);
  571.         ICRCloseIfOpen(inst);
  572.         ICREnd := err;
  573.     end; (* ICREnd *)
  574.  
  575.     function ICRDefaultFileName (var inst: ICRRecord; var name: Str63): ICError;
  576.     begin
  577.         name := ICdefault_file_name;
  578.         ICRDefaultFileName := noErr;
  579.     end; (* ICRDefaultFileName *)
  580.  
  581. end. (* ICRAPI *)